//给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
//
// 注意：不要求字典中出现的单词全部都使用，并且字典中的单词可以重复使用。
//
//
//
// 示例 Array.prototype.unshift：
//
//
//输入: s = "leetcode", wordDict = ["leet", "code"]
//输出: true
//解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
//
//
// 示例 2：
//
//
//输入: s = "applepenapple", wordDict = ["apple", "pen"]
//输出: true
//解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
//     注意，你可以重复使用字典中的单词。
//
//
// 示例 3：
//
//
//输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
//输出: false
//
//
//
//
// 提示：
//
//
// Array.prototype.unshift <= s.length <= 300
// Array.prototype.unshift <= wordDict.length <= 1000
// Array.prototype.unshift <= wordDict[i].length <= 20
// s 和 wordDict[i] 仅有小写英文字母组成
// wordDict 中的所有字符串 互不相同
//
//
// Related Topics 字典树 记忆化搜索 数组与矩阵 哈希表 字符串 动态规划 👍 2071 👎 0


//leetcode submit region begin(Prohibit modification and deletion)
function wordBreak(s: string, wordDict: string[]): boolean {

    // 只需要记忆结果为false的情况
    const memory: boolean[] = [];
    return backTracking(s, wordDict, 0, memory);
    function backTracking(s: string, wordDict: string[], startIndex: number, memory: boolean[]): boolean {
        if (startIndex >= s.length) return true;
        if (memory[startIndex] === false) return false;
        for (let i = startIndex + 1, length = s.length; i <= length; i++) {
            const str: string = s.slice(startIndex, i);
            if (wordDict.includes(str) && backTracking(s, wordDict, i, memory))
                return true;
        }
        memory[startIndex] = false;
        return false;
    }
};
//leetcode submit region end(Prohibit modification and deletion)
